<template>
    <div class="chart-container" ref="chartRef"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import * as echarts from 'echarts';
import { line4StationData, line4EdgesData, line6StationData, line6EdgesData } from '@/data/mapPoint';
import { errorNotify } from '@/utils/Misc';
const emit = defineEmits(['stationChange']);
const chartRef = ref(null);
let myChart = null;
let xiamenMapTimer = null;
let currentLine = 0;
let currentStationIndex = 0;
let currentTooltipStatus = { seriesIndex: -1, dataIndex: -1 };
const formatDateTime = () => {
    const date = new Date();
    const options = {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false
    };
    return date.toLocaleString('zh-CN', options);
};
const initChart = () => {
    if (myChart) myChart.dispose();
    myChart = echarts.init(chartRef.value);
    const option = {
        tooltip: {
            show: true,
            trigger: 'item',
            triggerOn: 'none',
            backgroundColor: 'rgba(17, 34, 68, 0.9)',
            borderColor: '#409EFF',
            borderWidth: 1,
            borderRadius: 8,
            padding: 12,
            textStyle: {
                color: '#FFFFFF',
                fontSize: 14,
                lineHeight: 1.6
            },
            formatter: (params) => {
                if (params.componentType === 'geo') {
                    return `<div class="tooltip-header">${params.name}</div>
                            <div class="tooltip-content">更新时间: ${formatDateTime()}</div>`;
                }
                return params.name;
            },
            transitionDuration: 0.3,
            shadowBlur: 10,
            shadowColor: 'rgba(64, 158, 255, 0.3)',
            hideOnClick: false
        },
        geo: {
            map: 'ch',
            zoom: 1.25,
            label: {
                show: false,
                textBorderColor: '#fff',
                textBorderWidth: 2,
                fontSize: 12,
                formatter: (params) => params.name === '福建' ? '福建' : ''
            },
            itemStyle: {
                areaColor: '#4C60FF',
                borderColor: '#1431CB',
                borderWidth: 1.5,
                shadowColor: 'rgba(30, 144, 255, 0.2)',
                shadowBlur: 15
            },
            emphasis: { itemStyle: { areaColor: '#293FFF' } }
        },
        series: [{
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: [{ name: '厦门', value: [118.11846, 24.565449] }],
            rippleEffect: { period: 3, scale: 6, brushType: 'fill' },
            symbolSize: 12,
            itemStyle: { color: '#FFD700', shadowBlur: 10, shadowColor: '#FFA500' },
            label: {
                show: true,
                position: 'right',
                formatter: '{b}',
                color: '#fff',
                fontSize: 14,
                fontWeight: 'bold'
            },
            zlevel: 10
        }]
    };
    myChart.setOption(option);
};
const xiamenOption = {
    toolbox: {
        show: true,
        feature: {
            restore: {
                show: true,
                title: '重置',
                iconStyle: {
                    color: '#409EFF',
                    borderColor: '#fff'
                }
            }
        }
    },
    tooltip: {
        show: true,
        trigger: 'item',
        triggerOn: 'none',
        backgroundColor: 'rgba(17, 34, 68, 0.95)',
        borderColor: '#409EFF',
        borderWidth: 1,
        borderRadius: 8,
        padding: 14,
        textStyle: {
            color: '#E6F7FF',
            fontSize: 14,
            lineHeight: 20
        },
        formatter: (params) => {
            if (params.seriesType === 'graph' && params.dataType === 'node') {
                const lineName = params.seriesIndex === 0 ? '地铁4号线' : '地铁6号线';
                const lineColor = params.seriesIndex === 0 ? '#FF0000' : '#805ad5';
                const status = Math.random() > 0.2 ? '正常' : '预警';
                const statusColor = status === '正常' ? '#52C41A' : '#FAAD14';
                return `<div style="width: 240px;">
                <div style="display: flex; align-items: center; margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid rgba(64, 158, 255, 0.2);">
                    <span style="width: 12px; height: 12px; border-radius: 50%; background: ${lineColor}; margin-right: 8px; flex-shrink: 0;"></span>
                    <div style="text-align: left;">
                        <span style="font-weight: 600; font-size: 15px; color: #E6F7FF;">${lineName} / </span>
                        <span style="font-size: 13px; color: #FFFFFF; margin-top: 2px;">${params.data.name}</span>
                    </div>
                </div>
                <div style="display: flex; margin-bottom: 6px; line-height: 1.5;">
                    <span style="width: 80px; color: #B0C4DE; text-align: left; flex-shrink: 0;">运行状态:</span>
                    <span style="color: ${statusColor}; font-weight: 500; text-align: left;">${status}</span>
                </div>
                <div style="display: flex; line-height: 1.5;">
                    <span style="width: 80px; color: #B0C4DE; text-align: left; flex-shrink: 0;">更新时间:</span>
                    <span style="color: #FFFFFF; text-align: left;">${formatDateTime()}</span>
                </div>
            </div>`;
            }
            if (params.componentType === 'geo') {
                return `<div style="min-width: 180px;">
                <div style="font-weight: 600; margin-bottom: 6px; color: #E6F7FF; text-align: left;">${params.name}</div>
                <div style="display: flex; line-height: 1.5;">
                    <span style="width: 80px; color: #B0C4DE; text-align: left; flex-shrink: 0;">更新时间:</span>
                    <span style="color: #FFFFFF; text-align: left;">${formatDateTime()}</span>
                </div>
            </div>`;
            }
            return params.name;
        },
        transitionDuration: 0.3,
        shadowBlur: 12,
        shadowColor: 'rgba(64, 158, 255, 0.4)',
        position: (point, params, dom, rect, size) => {
            const x = point[0];
            const y = point[1];
            const viewWidth = size.viewSize[0];
            const viewHeight = size.viewSize[1];
            const domWidth = dom.offsetWidth;
            const domHeight = dom.offsetHeight;
            const finalX = x + domWidth > viewWidth ? x - domWidth - 10 : x + 10;
            const finalY = y + domHeight > viewHeight ? y - domHeight - 10 : y + 10;
            return [finalX, finalY];
        },
        hideOnClick: false
    },
    geo: {
        map: 'xiamen',
        roam: true,
        label: {
            show: true,
            textBorderColor: '#fff',
            textBorderWidth: 2,
            fontSize: 12,
            color: '#E6F7FF'
        },
        center: [118.11846, 24.565449],
        zoom: 4,
        itemStyle: {
            areaColor: '#1a365d',
            borderColor: '#4a90e2',
            borderWidth: 1.5,
            shadowColor: 'rgba(30, 144, 255, 0.2)',
            shadowBlur: 15
        },
        emphasis: {
            itemStyle: { areaColor: '#3182ce' },
            label: { color: '#FFFFFF' }
        }
    },
    series: [
        {
            type: 'graph',
            coordinateSystem: 'geo',
            data: line4StationData,
            edges: line4EdgesData,
            edgeSymbol: ['none'],
            edgeSymbolSize: 5,
            symbol: 'pin',
            symbolSize: 20,
            lineStyle: { color: '#FF0000', opacity: 1, width: 2 },
            itemStyle: { color: '#FF0000', borderColor: '#fff', borderWidth: 2 },
            label: { show: false },
            emphasis: {
                label: { show: false },
                itemStyle: {
                    color: '#FF4500',
                    borderColor: '#FFE4B5',
                    shadowBlur: 8,
                    shadowColor: 'rgba(255, 0, 0, 0.5)'
                }
            }
        },
        {
            type: 'graph',
            coordinateSystem: 'geo',
            data: line6StationData,
            edges: line6EdgesData,
            edgeSymbol: ['none'],
            edgeSymbolSize: 5,
            symbol: 'pin',
            symbolSize: 20,
            lineStyle: { color: '#805ad5', opacity: 1, width: 2 },
            itemStyle: { color: '#805ad5', borderColor: '#fff', borderWidth: 2 },
            label: { show: false },
            emphasis: {
                label: { show: false },
                itemStyle: {
                    color: '#9F7AEA',
                    borderColor: '#E9D8FD',
                    shadowBlur: 8,
                    shadowColor: 'rgba(128, 90, 213, 0.5)'
                }
            }
        }
    ]
};
const fetchGeoJSON = () => {
    if (myChart) myChart.showLoading({
        text: 'Loading map data...',
        spinnerRadius: 20,
        textStyle: { color: '#409EFF', fontSize: 14 }
    });
    fetch('/dashboard/geo/china.geo.json')
        .then(response => {
            if (!response.ok) throw new Error('中国地图加载失败');
            return response.json();
        })
        .then(geoJSON => {
            echarts.registerMap('ch', geoJSON);
            initChart();
            bindChartEvents();
        }).catch(error =>
            errorNotify("MapPanel.vue", "fetchChinaGeoJSON", error)
        ).finally(() =>
            myChart && myChart.hideLoading()
        );
};
const bindChartEvents = () => {
    myChart.on('restore', () => {
        emit('stationChange', { isVisible: false });
        myChart.dispatchAction({ type: 'hideTip' });
        currentTooltipStatus = { seriesIndex: -1, dataIndex: -1 };
        if (xiamenMapTimer) {
            clearInterval(xiamenMapTimer);
            xiamenMapTimer = null;
        }
    });
    myChart.on('click', (params) => {
        pauseTimer();
        if (params.componentType === 'geo') {
            myChart.dispatchAction({ type: 'hideTip' });
            currentTooltipStatus = { seriesIndex: -1, dataIndex: -1 };
            emit('stationChange', { isVisible: false });
            return;
        }
        if (params.seriesType === 'graph' && params.dataType === 'node') {
            handleStationClick(params);
            return;
        }
        if (params.name === '福建' || params.name === '厦门') {
            myChart.dispatchAction({ type: 'hideTip' });
            currentTooltipStatus = { seriesIndex: -1, dataIndex: -1 };
            startIdleTimer();
            fetch('/dashboard/geo/xiamen.geo.json')
                .then(response => {
                    if (!response.ok) throw new Error('厦门地图加载失败');
                    return response.json();
                })
                .then(xiamenGeoJSON => {
                    echarts.registerMap('xiamen', xiamenGeoJSON);
                    myChart.setOption(xiamenOption);
                }).catch(error =>
                    errorNotify("MapPanel.vue", "fetchxiamenGeoJSON", error)
                ).finally(() =>
                    myChart && myChart.hideLoading()
                );
        }
    });
    myChart.off('mouseover');
    myChart.off('mouseout');
    myChart.off('mousemove');
};
const showStationTooltip = (seriesIndex, dataIndex) => {
    if (!myChart) return;
    currentTooltipStatus = { seriesIndex, dataIndex };
    myChart.dispatchAction({ type: 'hideTip' });
    setTimeout(() => {
        myChart.dispatchAction({
            type: 'showTip',
            seriesIndex: seriesIndex,
            dataIndex: dataIndex,
            position: 'top'
        });
    }, 500);
};
const handleStationClick = (params) => {
    const currentOption = myChart.getOption();
    currentOption.series.forEach(series => {
        if (series.data) {
            series.data.forEach(item => {
                if (item.symbolSize) item.symbolSize = 20;
                if (item.label) item.label.show = false;
            });
        }
    });
    const targetData = currentOption.series[params.seriesIndex].data[params.dataIndex];
    targetData.symbolSize = 50;
    currentOption.geo[0].center = params.data.value;
    currentOption.geo[0].zoom = 10;
    myChart.setOption(currentOption);
    myChart.dispatchAction({
        type: 'geoRoam',
        animation: true,
        animationDuration: 1000,
        animationEasing: 'cubicOut'
    });
    showStationTooltip(params.seriesIndex, params.dataIndex);
    emit('stationChange', {
        isVisible: true,
        name: params.data.name || '未知站点',
        lineName: params.seriesIndex === 0 ? '地铁4号线' : '地铁6号线',
        status: Math.random() > 0.2 ? '正常' : '预警',
        updateTime: formatDateTime()
    });
};
const switchStation = () => {
    if (!myChart) return;
    const linesData = [line4StationData, line6StationData];
    const currentLineData = linesData[currentLine];
    const currentOption = myChart.getOption();
    currentOption.series.forEach(series => {
        if (series.data) {
            series.data.forEach(item => {
                if (item.symbolSize) delete item.symbolSize;
                if (item.label) item.label.show = false;
            });
        }
    });
    const targetData = linesData[currentLine][currentStationIndex];
    const seriesIndex = currentLine;
    currentOption.geo[0].center = targetData.value;
    currentOption.geo[0].zoom = 10;
    const stationDataIndex = currentOption.series[seriesIndex].data.findIndex(
        item => item.name === targetData.name
    );
    if (stationDataIndex !== -1) {
        currentOption.series[seriesIndex].data[stationDataIndex].symbolSize = 50;
    }
    myChart.setOption(currentOption);
    myChart.dispatchAction({
        type: 'geoRoam',
        animation: true,
        animationDuration: 1000,
        animationEasing: 'cubicOut'
    });
    if (stationDataIndex !== -1) {
        showStationTooltip(seriesIndex, stationDataIndex);
    }
    emit('stationChange', {
        isVisible: true,
        name: targetData.name || '未知站点',
        lineName: currentLine === 0 ? '地铁4号线' : '地铁6号线',
        status: Math.random() > 0.2 ? '正常' : '预警',
        updateTime: formatDateTime()
    });
    if (currentStationIndex >= currentLineData.length - 1) {
        currentStationIndex = 0;
        currentLine = currentLine === 0 ? 1 : 0;
    } else {
        currentStationIndex++;
    }
};
const startIdleTimer = () => {
    if (xiamenMapTimer) clearInterval(xiamenMapTimer);
    xiamenMapTimer = setTimeout(() => {
        switchStation();
        xiamenMapTimer = setInterval(switchStation, 5000);
    }, 10000);
};
const pauseTimer = () => {
    if (xiamenMapTimer) {
        clearInterval(xiamenMapTimer);
        xiamenMapTimer = null;
    }
    startIdleTimer();
};
const resumeTimer = () => {
    if (!xiamenMapTimer) {
        xiamenMapTimer = setInterval(switchStation, 5000);
    }
};
const handleResize = () => {
    if (!myChart || currentTooltipStatus.seriesIndex === -1) return;
    myChart.resize();
    showStationTooltip(
        currentTooltipStatus.seriesIndex,
        currentTooltipStatus.dataIndex
    );
};
onMounted(() => {
    nextTick(() => fetchGeoJSON());
    window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
    if (xiamenMapTimer) clearInterval(xiamenMapTimer);
    window.removeEventListener('resize', handleResize);
    if (myChart) {
        myChart.dispose();
        myChart = null;
    }
});
defineExpose({ pauseTimer, resumeTimer });
</script>
<style scoped>
.chart-container {
    width: 100%;
    height: 100%;
    min-height: 0;
    overflow: hidden;
}

:deep(.tooltip-header) {
    font-weight: 600;
    font-size: 15px;
    color: #409EFF;
    margin-bottom: 8px;
    border-bottom: 1px solid rgba(64, 158, 255, 0.3);
    padding-bottom: 6px;
}

:deep(.tooltip-content) {
    color: #E6F7FF;
    line-height: 20px;
}
</style>